1 //+-----------------------------------------------------------------------
3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // Implements the PersistMoniker class of PresentationHost.
11 // 2003/06/30/03-[....]
12 // Ported ByteRangeDownloader to WCP
14 // Ported Windows->DevDiv. See SourcesHistory.txt.
15 // Removed dependence on ByteWrapper[Impl] and DownloadInfo for PresentationHost.exe.
17 //------------------------------------------------------------------------
19 #include "Precompiled.hxx"
20 #include "PersistMoniker.hxx"
21 #include "HostShim.hxx"
22 #include "BindStatusCallback.hxx"
23 #include "ShimUtilities.hxx"
25 //******************************************************************************
27 // CPersistMoniker::CPersistMoniker()
29 //******************************************************************************
31 CPersistMoniker::CPersistMoniker(__in CHostShim
*pHostShim
)
33 m_pHostShim
= pHostShim
;
36 //*******************************************************************************
38 // CPersistMoniker::~CPersistMoniker()
40 //******************************************************************************
42 CPersistMoniker::~CPersistMoniker()
46 //******************************************************************************
48 // CPersistMoniker::QueryInterface()
50 //******************************************************************************
52 STDMETHODIMP
CPersistMoniker::QueryInterface(REFIID riid
, __out LPVOID
*ppReturn
)
54 return m_pHostShim
->QueryInterface(riid
, ppReturn
);
57 //******************************************************************************
59 // CPersistMoniker::AddRef()
61 //******************************************************************************
63 STDMETHODIMP_(ULONG
) CPersistMoniker::AddRef()
65 return m_pHostShim
->AddRef();
68 //******************************************************************************
70 // CPersistMoniker::Release()
72 //******************************************************************************
74 STDMETHODIMP_(ULONG
) CPersistMoniker::Release()
76 return m_pHostShim
->Release();
79 //******************************************************************************
81 // CPersistMoniker::GetClassID()
83 //******************************************************************************
85 STDMETHODIMP
CPersistMoniker::GetClassID(__out LPCLSID pClassID
)
87 return m_pHostShim
->GetClassID(pClassID
);
90 //******************************************************************************
92 // CPersistMoniker::Save()
94 //******************************************************************************
96 STDMETHODIMP
CPersistMoniker::Save(LPMONIKER
, LPBC
, BOOL
)
101 //******************************************************************************
103 // CPersistMoniker::GetCurMoniker()
105 //******************************************************************************
107 STDMETHODIMP
CPersistMoniker::GetCurMoniker(LPMONIKER
*)
112 //******************************************************************************
114 // CPersistMoniker::SaveCompleted()
116 //******************************************************************************
118 STDMETHODIMP
CPersistMoniker::SaveCompleted(LPMONIKER
, LPBC
)
123 #define MAX_SCHEMA 64
125 //******************************************************************************
127 // CPersistMoniker::Load()
129 //******************************************************************************
131 STDMETHODIMP
CPersistMoniker::Load(BOOL fFullyAvailable
,
132 __in LPMONIKER pMoniker
,
138 EventWriteWpfHostUm_IPersistMonikerLoadStart();
140 m_pHostShim
->SetActivationType(MonikerActivation
);
142 LPOLESTR pwszURL
= NULL
;
143 WCHAR pszResult
[INTERNET_MAX_URL_LENGTH
+ 1];
145 CComPtr
<CBindStatusCallback
> spBindStatusCallback
;
146 CComPtr
<IFillLockBytes
> spFlb
;
147 CComPtr
<IMoniker
> spMkNew
;
148 CComPtr
<IBindCtx
> spBCNew
;
150 m_pHostShim
->SetAllowPersistFileLoad(FALSE
);
153 CKHR(pMoniker
->GetDisplayName(pbc
, pMoniker
, &pwszURL
));
155 m_pHostShim
->SetStartupUri(pwszURL
);
158 CKHR(CoInternetParseUrl(pwszURL
,
162 INTERNET_MAX_URL_LENGTH
+ 1,
165 // If we are a local file, FAIL to load from the IPersistMoniker
166 // so that we will load from the IPersistFile, instead.
170 if (cchResult
== 4 && _wcsnicmp(pszResult
,L
"file",4) == 0)
174 hr
= E_FAIL
; // E_FAIL
178 hr
= S_FALSE
; // S_FALSE
181 //Returning E_NOTIMPL for now to work around a urlmon bug
184 //We will allow IPersistFile::Load only for local files. If IPersistMoniker::Load
185 //fails for http urls, urlmon will then call IPersistFile::Load with the
186 //cache filename. It is unsafe and incorrect for us to allow that load since
187 //we will grant elevated security privileges and also relative references will
189 m_pHostShim
->SetAllowPersistFileLoad(TRUE
);
194 spBindStatusCallback
= new CBindStatusCallback();
195 CK_ALLOC(spBindStatusCallback
);
196 //!!! Make sure to set BINDINFO_OPTIONS_ENABLE_UTF8 in all implementations of IBindStatusCallback.
197 //!!! It is needed for correct encoding of non-ASCII characters in URL paths, per RFC 3986 & 3987.
199 // UrlMon Workaround: UrlMon was returning the wrong file size information for files that
200 // were in the cache. Our past workaround was to delete the cache file, however IE suggested
201 // that we create a new Moniker and BindContext before binding to storage. This would allow
202 // us to use the cache file if the content has not expired.
203 CKHR(CreateURLMonikerEx(NULL
, pwszURL
, &spMkNew
, URL_MK_UNIFORM
));
204 CKHR(CreateBindCtx( 0, &spBCNew
));
205 CKHR(RegisterBindStatusCallback(spBCNew
, spBindStatusCallback
, NULL
, 0));
207 CKHR(spMkNew
->BindToStorage(spBCNew
,
210 reinterpret_cast<void**>(&(spBindStatusCallback
->m_pStream
))));
216 BOOL fReceivedWmQuit
;
218 MsgWaitForSingleObject(spBindStatusCallback
->m_hMimeArrivedEvent
, INFINITE
, &fReceivedWmQuit
);
220 m_pHostShim
->SetMimeType(spBindStatusCallback
->GetMimeType());
222 if ((m_pHostShim
->GetMimeType() == MimeType_Application
) ||
223 (m_pHostShim
->GetMimeType() == MimeType_Markup
))
225 MsgWaitForSingleObject(spBindStatusCallback
->m_hManifestAvailableEvent
, INFINITE
, &fReceivedWmQuit
);
226 m_pHostShim
->SetLocalDeploymentManifestPath(spBindStatusCallback
->GetCacheFilename());
227 // Trigger DownloadCompleted since downloading is performed in managed code.
228 SignalAvalonStartupRelatedEvent(m_pHostShim
->GetDownloadCompletedEvent());
235 // Note: CHostShim::Execute() is called below.
239 // We purposefully return E_FAIL to cause IPersistFile loading.
240 if (!m_pHostShim
->GetAllowPersistFileLoad())
242 // Handle downloading error from UrlMon
243 if (FAILED(hr
) && spBindStatusCallback
)
245 HRESULT bindResult
= spBindStatusCallback
->GetBindResult();
246 if(FAILED(bindResult
))
249 wchar_t *pErrMsg
= TryDecodeDownloadError(hr
);
252 // The easiest thing to do is call MessageBox() here. But the browser still has the
253 // foreground window status, so the message box will show minimized or behind.
254 // The solution is to fully activate the DocObject so that it can show the error page.
255 m_pHostShim
->SetErrorMessageToDisplay(pErrMsg
);
257 hr
= S_OK
; // Don't fail. We are activating, after all.
264 // Note: Execute() triggers Watson on any failure.
265 m_pHostShim
->Execute();
269 HANDLE_ACTIVATION_FAULT(hr
);
275 CoTaskMemFree(pwszURL
);
278 EventWriteWpfHostUm_IPersistMonikerLoadEnd(hr
);
283 //******************************************************************************
285 // CPersistMoniker::IsDirty()
287 //******************************************************************************
289 STDMETHODIMP
CPersistMoniker::IsDirty()